#include "hj212_client_def.h"
#include "hj212_base_request.h"
#include "hj212_msg.h"
#include "hj212_pack.h"
#include "hj212_client_ops.h"
#include "hj212_msg.h"
#include "hj212_data_stream.h"
#include <stdio.h>

/* *
 * 所有数据请求
 *
 *
 */

struct data_request
{
    struct hj212_request parent;
    struct hj212_datastream *stream;    // 数据请求中带数据源
};

static int data_request_handle(struct hj212_client *client, struct hj212_request *request)
{
    struct data_request *this = (struct data_request *)request;
    int stream_state = get_hj212_datastream_state(this->stream);
    if (stream_state == HJ212_DATASTREAM_IDLE)
    {
        int maxret = 0;    // 不响应
        hj212_client_command(client, GET_HJ212_MAXRET, &maxret);
        hj212_datastream_push(this->stream, client, !!maxret);
    }
    else if (stream_state == HJ212_DATASTREAM_EMPTY)
    {
        // 请求结束 返回成功
        hj212_commit_request_result(client, REQUEST_EXE_RESULT_SUCCEED, request);

        hj212_client_delete_data_source(client, this->stream->source);
        hj212_datastream_delete(client, this->stream);

        hj212_request_destroy(request);
        hj212_client_free(client, this);
    }
    return 0;
}

int hj212_data_request_match(struct hj212_client *client,
                             struct hj212_generalmsg *msg,
                             uint32_t package_state)
{
    int type = hj212_datamsg_cn_to_type(msg->parent.cn);
    if (type < HJ212_MSG_TYPE_MIN && type > HJ212_MSG_TYPE_DAY)  // 这个请求只有分钟小时日
    {
        return -1;
    }
    int res = hj212_standard_request_preprocessing(client, msg, package_state, msg->parent.cn);
    if (res < 0)
    {
        return res;
    }
    if (!res)
    {
        if (package_state & UNPACK_NO_CP)
        {
            hj212_commit_request_result_frommsg(client, REQUEST_EXE_RESULT_INVALID_PARAM, msg);
            return 0;
        }
        const char *b_time_p = strstr(msg->cp, "BeginTime=");
        const char *e_time_p = strstr(msg->cp, "EndTime=");
        if (!b_time_p || !e_time_p)
        {
            hj212_commit_request_result_frommsg(client, REQUEST_EXE_RESULT_INVALID_PARAM, msg);
            return 0;
        }

        struct tm begin_time;
        struct tm end_time;

        int b_res = sscanf(b_time_p, "BeginTime=%04d%02d%02d%02d%02d%02d",
                           &begin_time.tm_year, &begin_time.tm_mon, &begin_time.tm_mday,
                           &begin_time.tm_hour, &begin_time.tm_min, &begin_time.tm_sec);
        int e_res = sscanf(e_time_p, "EndTime=%04d%02d%02d%02d%02d%02d",
                           &end_time.tm_year, &end_time.tm_mon, &end_time.tm_mday,
                           &end_time.tm_hour, &end_time.tm_min, &end_time.tm_sec);
        if (b_res != 6 || e_res != 6)
        {
            hj212_commit_request_result_frommsg(client, REQUEST_EXE_RESULT_INVALID_PARAM, msg);
            return 0;
        }

        begin_time.tm_year -= 1900;
        end_time.tm_year -= 1900;
        begin_time.tm_mon -= 1;
        end_time.tm_mon -= 1;

        time_t BeginTime = mktime(&begin_time);
        time_t EndTime = mktime(&end_time);

        struct data_request *request = hj212_client_calloc(client, 1, sizeof(struct data_request));
        if (!request)
        {
            hj212_commit_request_result_frommsg(client, REQUEST_EXE_RESULT_FAULT, msg);
            return 0;
        }
        struct hj212_datasource *source = hj212_client_create_hisdata_source(client, type, BeginTime, EndTime);
        struct hj212_datastream *stream = hj212_datastream_create(client, type, source);
        if (!stream)
        {
            hj212_commit_request_result_frommsg(client, REQUEST_EXE_RESULT_UNKNOWN_ERROR, msg);
            if (source)
            {
                hj212_client_free(client, request);
                hj212_client_delete_data_source(client, source);
            }
            return 0;
        }
        request->stream = stream;
        hj212_request_init(&request->parent, msg->parent.qn, msg->parent.cn, data_request_handle, client);
    }
    return 0;
}

